package controller.transform;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

import javax.media.j3d.Transform3D;
import javax.vecmath.Vector3d;

import math.Transforms;

import component.AbstractComponent;
import component.Ball;
import component.Status;
import component.group.ComponentGroup;
import controller.camera.Camera;

public class RotatePivotMode extends RotateMode {

	private Ball pivot;
	
	private int lastX=0;
	private int lastY=0;
	
	private Vector3d camZ = new Vector3d(1, 0, 0);
	private Vector3d camY = new Vector3d(0, 1, 0);
	
	public RotatePivotMode(Gui gui, Scene scene, Ball pivot) {
		super(gui, scene);
		gui.lockCamera();
		this.pivot = pivot;
		this.pivot.setStatus(Status.HIGHLIGHTED, true);
		border = new ComponentGroup();
		border.add(pivot);
		this.setDefaultHelp();
		this.updateLeftUp();
		transformHistory.setIdentity();
	}

	@Override
	public TransformMode mousePressed(MouseEvent e) {
		if (e.getButton() == MouseEvent.BUTTON3) {
			this.reset();
			return new InitMode(gui, scene);
		}
		transformHistory.setIdentity();
		AbstractComponent component = scene.pickClosest(e);
		if (component != pivot)
			selectComponent(component);
		lastX = e.getX();
		lastY = e.getY();
		return this;
	}
	

	@Override
	public TransformMode mouseReleased(MouseEvent e) {
		if (grabbedSelection != null) {
			if (!grabbedSelection.isValidPosition()) {
				undo();
			} else {
				scene.connectPossible();
			}
		}
		unselectComponent();
		this.setDefaultHelp();
		return this;
	}

	@Override
	public TransformMode mouseMoved(MouseEvent e) {
		return this;
	}

	@Override
	public TransformMode mouseDragged(MouseEvent e) {
		if (grabbedSelection == null) return this;
		if (grabbedSelection.containsLockedComponents())
			return this;
		int deltaX = e.getX() - lastX;
		int deltaY = e.getY() - lastY;
		
		lastX = e.getX();
		lastY = e.getY();
		
		Transform3D transform = Transforms.makePivotRotation(pivot.getPos(), camY, camZ, deltaX, deltaY);
		
		grabbedSelection.applyTransform(transform);
		transformHistory.mul(transform, transformHistory);
		
		if (grabbedSelection.isValidPosition()) {
			this.setLegalGroupState();
		} else {
			this.setIllegalGroupState();
		}
		
		return this;
	}

	@Override
	public TransformMode keyPressed(KeyEvent e) {
		return this;
	}

	@Override
	public TransformMode keyReleased(KeyEvent e) {
		return this;
	}

	@Override
	public void deselected() {
		reset();
		gui.unlockCamera();
	}
	
	private void reset() {
		this.pivot.setStatus(Status.NORMAL);
	}
	
	private void updateLeftUp() {
		Vector3d right;
		Vector3d front = new Vector3d(gui.getCameraFocus());
		front.sub(gui.getCameraPosition());
		right = new Vector3d();
		camY = new Vector3d();
		right.cross(front, Camera.DEFAULT_UP);
		camY.cross(right, front);
		right.normalize();
		camY.normalize();
		camZ.negate(front);
	}

}
